package util

import (
	"database/sql/driver"
	"encoding/json"
	"errors"
)

// Json is a custom type that can be used to scan JSON data from a database
type Json map[string]interface{}

// Scan implements the Scanner interface.
func (j *Json) Scan(value interface{}) error {
	b, ok := value.([]byte)
	if !ok {
		return errors.New("type assertion to []byte failed")
	}

	return json.Unmarshal(b, &j)
}

// Value implements the driver Valuer interface.
func (j Json) Value() (driver.Value, error) {
	return json.Marshal(j)
}

// JsonArray is a custom type that can be used to scan JSON array data from a database
type JsonArray []interface{}

// Scan implements the Scanner interface.
func (ja *JsonArray) Scan(value interface{}) error {
	b, ok := value.([]byte)
	if !ok {
		return errors.New("type assertion to []byte failed")
	}

	return json.Unmarshal(b, &ja)
}

// Value implements the driver Valuer interface.
func (ja JsonArray) Value() (driver.Value, error) {
	return json.Marshal(ja)
}

// Location is a custom type that can be used to scan location data from a database
type Location struct {
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
}

// Scan implements the Scanner interface.
func (l *Location) Scan(value interface{}) error {
	b, ok := value.([]byte)
	if !ok {
		return errors.New("type assertion to []byte failed")
	}

	return json.Unmarshal(b, &l)
}

// Value implements the driver Valuer interface.
func (l Location) Value() (driver.Value, error) {
	return json.Marshal(l)
}
